home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr37 / satsfaxt.zip / CCPUTILS.ZIP / CCSTAT.C < prev    next >
Text File  |  1990-01-30  |  45KB  |  884 lines

  1. /*---------------------------------------------------------------------------*
  2.  *                                 CCSTAT.C                                  *
  3.  *---------------------------------------------------------------------------*
  4.  * The program allows the user to view the contents of the receive/send/log  *
  5.  * queues as defined in the DCA/Intel CAS 1.0A specification. Additionally,  *
  6.  * the hardware status can be viewed and on-board diagnostics can be         *
  7.  * run. All options, filenames and addresses are specified on the            *
  8.  * command line.                                                             *
  9.  *                                                                           *
  10.  * The following source code is intended to assist developers in             *
  11.  * creating applications which support the  DCA/Intel Communicating          *
  12.  * Applications Specification Version 1.0A. It is provided free of charge    *
  13.  * and on an as-is basis. THE IMPLIED WARRANTIES OF MERCHANTABILITY AND      *
  14.  * FITNESS FOR A PARTICULAR PURPOSE ARE SPECIFICALLY EXCLUDED. This source   *
  15.  * code may be modified, enhanced, copied and distributed with applications  *
  16.  * that support CAS on a royalty free basis.                                 *
  17.  *---------------------------------------------------------------------------*/
  18. #include <stdio.h>
  19. #include <dos.h>
  20. #include <io.h>
  21. #include <malloc.h>
  22. #include <string.h>
  23. #include "cas.h"                /* Intel CAS header file.                    */
  24. #include "parse.h"              /* Command line parser header file.          */
  25. #include "util.h"               /* CAS utilities header file.                */
  26.  
  27. #define UpperBound(a)   (sizeof(a)/sizeof(a[0]))
  28.  
  29. int Diagnostics = FALSE;        /* Run diagnostics if TRUE.                  */
  30. int HardwareOnly = FALSE;       /* Show only the status of hardware if TRUE. */
  31. char *JobNo = "0";              /* Show status of single job.                */
  32. unsigned long EventNo = 0L;     /* Converted job number.                     */
  33. int TransmitOnly = FALSE;       /* Show Task Queue if TRUE.                  */
  34. int LogOnly = FALSE;            /* Show Log Queue if TRUE.                   */
  35. int ShowAll = FALSE;            /* Show Task & Log Queues if TRUE.           */
  36. int CurrentEvent = FALSE;       /* Show Current Event if TRUE.               */
  37. int ARState = FALSE;            /* Show autoreceive state.                   */
  38. int AnswerOnRing = -1;          /* Set autoreceive state.                    */
  39. int Help = FALSE;               /* Show help text.                           */
  40. int NewOnly = FALSE;            /* Show only new tasks.                      */
  41. int RedirOut = FALSE;           /* Redirect output to file.                  */
  42.  
  43. CECS *TSTATbuffer;              /* Task status buffer.                       */
  44. ECF *TCFbuffer;                 /* Task Control File buffer.                 */
  45. FTR *FTRbuffer;                 /* File Transfer Record buffer.              */
  46. EDB *EDBbuffer;                 /* External Data Block buffer.               */
  47. FILE *ccout;                    /* Redirected stdout file.                   */
  48. int FileHandle;                 /* File handle of Task Control File.         */
  49.  
  50. /* CAS errors (exit code field is the CAS error number). */
  51. ERRORMSG CASEmsg[] = {
  52.     { 0x0000, "" },
  53.     { 0x0002, "Image file is corrupted" },
  54.     { 0x0003, "File was sent, but it might contain errors" },
  55.     { 0x0004, "Receive data lost" },
  56.     { 0x0005, "Invalid or missing logofile" },
  57.     { 0x0006, "File name doesn't match NSF header" },
  58.     { 0x0007, "File size doesn't match NSF header" },
  59.     { 0x0200, "Internal error. Task switch failed" },
  60.     { 0x0201, "Unknown command" },
  61.     { 0x0202, "Event not found" },
  62.     { 0x0203, "Tried to findnext with previous findfirst" },
  63.     { 0x0204, "No more events" },
  64.     { 0x0207, "Unknown schedule division" },
  65.     { 0x0208, "Bad event control file" },
  66.     { 0x0209, "Connection CoProcessor is busy" },
  67.     { 0x020A, "Invalid PCAM parameter" },
  68.     { 0x020B, "Can't uninstall PCAM" },
  69.     { 0x020C, "File already exists" },
  70.     { 0X0280, "Unknown task type" },
  71.     { 0X0281, "Bad phone number" },
  72.     { 0X0282, "Bad .PCX file header" },
  73.     { 0X0283, "Unexpected end of file" },
  74.     { 0X0284, "Phone line disconnected during event" },
  75.     { 0X0286, "No files specified to send" },
  76.     { 0X0287, "Connection CoProcessor isn't responding" },
  77.     { 0X0288, "More than 1023 pages of receive data" },
  78.     { 0X0289, "Manual connect posted too long ago" },
  79.     { 0X028A, "Connection CoProcessor command set error" },
  80.     { 0X028B, "Bad NSF header file" },
  81.     { 0X0401, "Remote unit not Group 3 compatible" },
  82.     { 0X0402, "Remote unit didn't send its capabilities" },
  83.     { 0X0403, "Remote unit requested disconnect" },
  84.     { 0X0404, "Remote unit isn't a CCP" },
  85.     { 0X0405, "Exceeded retrain or fax resend limit" },
  86.     { 0X0406, "Line noise or CCP & remote don't agree on bit rate" },
  87.     { 0X0407, "Remote unit disconnected after receiving data" },
  88.     { 0X0408, "No reply from remote unit after sending data" },
  89.     { 0X0409, "Capabilities of remote unit aren't compatible" },
  90.     { 0X040B, "Invalid reply from remote unit after sending data" },
  91.     { 0X040D, "Phone line dead or remote unit disconnected" },
  92.     { 0X0411, "Invalid command from remote after receiving data" },
  93.     { 0X0415, "Tried to receive from incompatible hardware" },
  94.     { 0X041F, "Unexpected end of file while receiving" },
  95.     { 0X045D, "Remote unit unexpectedly stopped sending data" },
  96.     { 0X045E, "Remote unit didn't send any data" },
  97.     { 0X045F, "Remote unit took too long to send fax scan line" },
  98.     { 0X0463, "Can't get through to remote unit" },
  99.     { 0X0464, "User canceled event" }
  100. };
  101.  
  102. /* Argument table for command line processor. */
  103. STABLE SwitchTable[] =          /* Command line parser switch table. */
  104. {
  105.     { 'A', BOOL,   &ARState         },
  106.     { 'a', BOOL,   &ARState         },
  107.     { 'S', INT,    &AnswerOnRing    },
  108.     { 's', INT,    &AnswerOnRing    },
  109.     { 'D', BOOL,   &Diagnostics     },
  110.     { 'd', BOOL,   &Diagnostics     },
  111.     { 'H', BOOL,   &HardwareOnly    },
  112.     { 'h', BOOL,   &HardwareOnly    },
  113.     { 'E', STRING, (int *)&JobNo    },
  114.     { 'e', STRING, (int *)&JobNo    },
  115.     { 'L', BOOL,   &LogOnly         },
  116.     { 'l', BOOL,   &LogOnly         },
  117.     { 'P', BOOL,   &TransmitOnly    },
  118.     { 'p', BOOL,   &TransmitOnly    },
  119.     { 'N', BOOL,   &NewOnly         },
  120.     { 'n', BOOL,   &NewOnly         },
  121.     { 'C', BOOL,   &CurrentEvent    },
  122.     { 'c', BOOL,   &CurrentEvent    },
  123.     { 'R', BOOL,   &RedirOut        },
  124.     { 'r', BOOL,   &RedirOut        },
  125.     { '?', BOOL,   &Help            }
  126. };
  127. #define TABLESIZE (sizeof(SwitchTable)/sizeof(STABLE))
  128.  
  129. char *DescTable[] =             /* Help function description table. */
  130. {
  131.      "CCSTAT (V1.0) View contents of the send, receive, and log queues.\n\n",
  132.      "By specifying the appropriate options, you can view the hardware status and \n",
  133.      "run on-board diagnostics.\n\n",
  134.      "Syntax: CCSTAT [option...]\n\n"
  135. };
  136. #define DESCSIZE (sizeof(DescTable)/sizeof(DescTable[0]))
  137.  
  138. char *HelpTable[] =             /* Help function switch table. */
  139. {
  140.      "  /A           Display answer mode (# of rings before answer).\n",
  141.      "  /S<number>   Set answer mode.\n\n",
  142.      "  /E<number>   Display status of the event specified by number.\n\n",
  143.      "  /C           Display information about the current event.\n",
  144.      "  /N           Display only new events.\n",
  145.      "  /L           Display information about logged (completed) events.\n",
  146.      "  /P           Display information about pending events.\n",
  147.      "  /D           Run Connection CoProcessor diagnostics.\n",
  148.      "  /H           Display information about hardware status.\n\n",
  149.      "  /R           Redirect output to file OUTPUT.CC.\n",
  150.      "  /?           Display help information.\n"
  151. };
  152. #define HELPSIZE (sizeof(HelpTable)/sizeof(HelpTable[0]))
  153.  
  154. /*---------------------------------------------------------------------------*
  155.  *                             RunDiagnostics()                              *
  156.  *---------------------------------------------------------------------------*
  157.  * This function runs on-board diagnostics.  It will not return until the    *
  158.  * hardware has finished with the diagnostics routines.  The status (Pass    *
  159.  * or Fail) is displayed as appropriate.                                     *
  160.  *---------------------------------------------------------------------------*
  161.  * Parameters: none                                                          *
  162.  * Return:     none                                                          *
  163.  *---------------------------------------------------------------------------*/
  164. int RunDiagnostics()
  165. {
  166.     int result;                 /* Return value from CASRunDiagnostics.      */
  167.  
  168.     /* Start the diagnostics routine running. */
  169.     if((result = CASRunDiagnostics(START)) == SUCCESS)
  170.         fprintf(stdout, " Diagnostics started ");
  171.     else
  172.         CASError(CASDIAG, TRUE, -result);
  173.  
  174.     /* Check the status. This function returns only when diags are complete. */
  175.     while ((result = CASRunDiagnostics(STATUS)) == 0x40);
  176.     if (result == SUCCESS)
  177.         fprintf(stdout, "\r Diagnostics completed successfully.           \n");
  178.     else
  179.         CASError(CASHW, TRUE, -result);
  180. }
  181.  
  182. /*---------------------------------------------------------------------------*
  183.  *                            ShowHWStatus()                                 *
  184.  *---------------------------------------------------------------------------*
  185.  * Shows the current status of the Connection CoProcessor hardware.  The     *
  186.  * current status can be determined by checking the status of the current    *
  187.  * event.  Note that if there is no current event, CASGetTaskStatus          *
  188.  * has error code "-NO_MORE_EVENTS". This is not really an error- rather just*
  189.  * the fact that there is no current event on the board.                     *
  190.  *---------------------------------------------------------------------------*
  191.  * Parameters:  CECS *TSTATbuffer - Uninitialized CECS structure, filled     *
  192.  *                  with Task Control information about the current event.   *
  193.  *              EDB *EDBbuffer - Uninitialized EDB buffer, filled with       *
  194.  *                  External Data Block on return.                           *
  195.  * Return:      none                                                         *
  196.  *---------------------------------------------------------------------------*/
  197. ShowHWStatus(CECS *TSTATbuffer, EDB *EDBbuffer)
  198. {
  199.     int state;                  /* State of hardware.                        */
  200.     int EventHandle;            /* Current event handle.                     */
  201.     char msg[35];               /* Output message.                           */
  202.  
  203.     /* Fill the TSTATbuffer with information about the current event. */
  204.     if((EventHandle = CASGetCurrentEventStatus(TSTATbuffer)) > 0)
  205.         state = TSTATbuffer->ControlFile.EventStatus;
  206.     else
  207.         state = EventHandle;                    /* contains error code */
  208.  
  209.     switch (state) {
  210.         case -NO_MORE_EVENTS : /* Note: this is really an error value! */
  211.         case COMPLETED       : strcpy(msg, "Connection CoProcessor idle."); break;
  212.         case WAITING         : strcpy(msg, "Connection CoProcessor waiting."); break;
  213.         case DIALED          : strcpy(msg, "Connection CoProcessor dialing."); break;
  214.         case SENDING         : strcpy(msg, "Connection CoProcessor sending."); break;
  215.         case RECEIVING       : strcpy(msg, "Connection CoProcessor receiving."); break;
  216.         case ABORTED         : strcpy(msg, "Connection CoProcessor aborted."); break;
  217.     }
  218.     fprintf(stdout, "%s\n", msg);
  219.  
  220. }
  221.  
  222. /*---------------------------------------------------------------------------*
  223.  *                                GetTaskBuffer()                            *
  224.  *---------------------------------------------------------------------------*
  225.  * Opens the task control file and fill a TCFbuffer with the task control    *
  226.  * information.  The handle returned by the CAS function call is a normal    *
  227.  * MS-DOS file handle.                                                       *
  228.  *---------------------------------------------------------------------------*
  229.  * Parameters:  int Handle - Event handle to open.                           *
  230.  *              BYTE Queue - Queue (Task, Receive or Log) to search.         *
  231.  *              char *TCFbuffer - Uninitialized ECS structure, filled with   *
  232.  *                  Task Control info on return.                             *
  233.  *              int *FileHandle - Filled with DOS file handle on return.     *
  234.  * Return:      none                                                         *
  235.  *---------------------------------------------------------------------------*/
  236. GetTaskBuffer(int Handle, BYTE Queue, char *TCFbuffer, int *FileHandle)
  237. {
  238.  
  239.     /* Let CAS open the file and return the MS-DOS file handle. */
  240.     if((*FileHandle = CASOpenFile(Handle,0,Queue)) > 0) {
  241.         read(*FileHandle, TCFbuffer, sizeof(ECF));
  242.     }
  243.     else
  244.         CASError(CASNOTCF, TRUE, -(*FileHandle));
  245. }
  246.  
  247. /*---------------------------------------------------------------------------*
  248.  *                          GetFileTransferBuffer()                          *
  249.  *---------------------------------------------------------------------------*
  250.  * Reads a single file transfer buffer.  Normally, if the file does not      *
  251.  * contain cover page text this record will begin at offset 383 of the       *
  252.  * control file.  If there is cover page text, then you can find the offset  *
  253.  * of the first FTR record at offset 10 in the control file.  In either      *
  254.  * case, each additional FTR record is located 128 bytes past the start of   *
  255.  * the previous FTR.                                                         *
  256.  *---------------------------------------------------------------------------*
  257.  * Parameters:  lonf Offset - File offset to begin reading at.               *
  258.  *              char *FTRbuffer - Uninitialized FTR structure, filled with   *
  259.  *                  File Transfer info on return.                            *
  260.  *              int *FileHandle - DOS file handle obtained from a call to    *
  261.  *                  CASOpenFile().                                           *
  262.  * Return:      none                                                         *
  263.  *---------------------------------------------------------------------------*/
  264. GetFileTransferBuffer(long Offset, char *FTRbuffer, int *FileHandle)
  265. {
  266.     lseek(*FileHandle, Offset, SEEK_SET);
  267.     read(*FileHandle, FTRbuffer, sizeof(FTR));
  268. }
  269.  
  270. /*---------------------------------------------------------------------------*
  271.  *                               CorrectDate()                               *
  272.  *---------------------------------------------------------------------------*
  273.  * Converts a date as stored in a control file to a string that can be       *
  274.  * displayed on stdout.  The TCFbuffer must first be read from the control   *
  275.  * file.                                                                     *
  276.  *---------------------------------------------------------------------------*
  277.  * Parameters: ECF *TCFbuffer - Filled in ECS structure.                     *
  278.  *             char string[] - Array to place ascii date string.             *
  279.  * Return:     none                                                          *
  280.  *---------------------------------------------------------------------------*/
  281. CorrectDate(ECF *TCFbuffer, char string[])
  282. {
  283.     int day, month, year;       /* Vars to hold date values.                 */
  284.     int minute, hour;           /* Vars to hold time values.                 */
  285.  
  286.     day = TCFbuffer->EventDate & 0x001F;
  287.     month = (TCFbuffer->EventDate & 0x01E0) >> 5;
  288.     year = ((TCFbuffer->EventDate & 0xFE00) >> 9) + 1980;
  289.     minute = (TCFbuffer->EventTime & 0x07E0) >> 5;
  290.     hour = (TCFbuffer->EventTime & 0xF800) >> 11;
  291.  
  292.     sprintf(string, "%02d/%02d/%02d %02d:%02d", month, day, year, hour, minute);
  293.  
  294. }
  295.  
  296. /*---------------------------------------------------------------------------*
  297.  *                              ShowEventStatus()                            *
  298.  *---------------------------------------------------------------------------*
  299.  * Shows the status of the indicated queue.  Jobs are shown in               *
  300.  * chronological order.                                                      *
  301.  *---------------------------------------------------------------------------*
  302.  * Parameters:  int Status - Type (status) of events to search for.          *
  303.  *              BYTE Queue - What queue to search (Task, Receive, Log).      *
  304.  *              ECF *TCFbuffer - Uninitialized ECF structure.                *
  305.  *              FTR *FTRbuffer - Uninitialized FTR structure.                *
  306.  * Return:      none                                                         *
  307.  *---------------------------------------------------------------------------*/
  308. ShowQueueStatus(int Status, BYTE Queue, ECF *TCFbuffer, FTR *FTRbuffer)
  309. {
  310.  
  311.     int EventHandle;            /* Event handle.                             */
  312.     int Offset;                 /* FTR offset.                               */
  313.     int Count;                  /* File count.                               */
  314.     int NewEvents = 0;          /* # of new events in queue.                 */
  315.     int ShowIt = TRUE;          /* New events flag.                          */
  316.     char Date[20];              /* Date string.                              */
  317.     char EventStatus[10];       /* Event status string.                      */
  318.     char Action[8];             /* Event type.                               */
  319.     char TransType[5];          /* Transfer type string.                     */
  320.  
  321.     /* Find the first entry in the indicated queue. Call this function the
  322.        first time. Thereafter, call CASFindNext. */
  323.     if((EventHandle = CASFindFirst(Status,SEARCH_FORWARD,Queue)) > 0) {
  324.  
  325.         /* Get information about the event found above. Don't forget to close
  326.          * the file! */
  327.         GetTaskBuffer(EventHandle, Queue, (char *)TCFbuffer, &FileHandle);
  328.  
  329.         if(NewOnly) {
  330.             if((TCFbuffer->EventType == RECEIVE) || (TCFbuffer->EventType == POLLED_RECEIVE)) {
  331.                 Offset = TCFbuffer->FTROffset;
  332.                 for(Count = 1; Count <= TCFbuffer->FileCount; Count++) {
  333.                     /* Get information about the transferred files. */
  334.                     GetFileTransferBuffer((long)Offset, (char *)FTRbuffer, &FileHandle);
  335.                     Offset = Offset + 128;
  336.                     if(FTRbuffer->FileStatus != UNTOUCHED)
  337.                         ShowIt = FALSE;
  338.                 }
  339.             }
  340.             else
  341.                 /* Don't show sends or polled sends! */
  342.                 ShowIt = FALSE;
  343.  
  344.         }
  345.         close(FileHandle);
  346.         if(ShowIt) {
  347.             ++NewEvents;
  348.             CorrectDate(TCFbuffer, Date);
  349.  
  350.             switch(TCFbuffer->TransferType) {
  351.                 case FAX_200       : strcpy(TransType, "Fine"); break;
  352.                 case FAX_100       : strcpy(TransType, "Std "); break;
  353.                 case FILE_TRANSFER : strcpy(TransType, "CCP "); break;
  354.                 default            : strcpy(TransType, "    "); break;
  355.             }
  356.             switch(TCFbuffer->EventStatus) {
  357.                 case COMPLETED     : strcpy(EventStatus, "Completed"); break;
  358.                 case WAITING       : strcpy(EventStatus, "Waiting  "); break;
  359.                 case DIALED        : strcpy(EventStatus, "Dialed   "); break;
  360.                 case SENDING       : strcpy(EventStatus, "Sending  "); break;
  361.                 case RECEIVING     : strcpy(EventStatus, "Receiving"); break;
  362.                 case ABORTED       : strcpy(EventStatus, "Aborted  "); break;
  363.                 default            : strcpy(EventStatus, "Error    "); break;
  364.             }
  365.  
  366.             switch(TCFbuffer->EventType) {
  367.                 case SEND            : strcpy(Action, "Send"); break;
  368.                 case RECEIVE         : strcpy(Action, "Recv"); break;
  369.                 case POLLED_SEND     : strcpy(Action, "Send(P)"); break;
  370.                 case POLLED_RECEIVE  : strcpy(Action, "Recv(P)"); break;
  371.                 default              : strcpy(Action, "Error"); break;
  372.             }
  373.  
  374.             /* Display information. */
  375.             fprintf(stdout, "\n%6d %14s %-8s %4s %9s %-6s%-24s",
  376.                 EventHandle,
  377.                 Date,
  378.                 Action,
  379.                 TransType,
  380.                 EventStatus,
  381.                 TCFbuffer->EventType ? "From:":"  To:",
  382.                 TCFbuffer->EventType ? TCFbuffer->SenderName : TCFbuffer->DestinationName);
  383.         }
  384.         /* Find the remaining entries in the indicated queue. The parametes
  385.          * for status and direction are used from the last call to
  386.          * CASFindFirst. */
  387.         while((EventHandle = CASFindNext(Queue)) > 0) {
  388.             ShowIt = TRUE;
  389.             /* Again, read the information and display it. */
  390.             GetTaskBuffer(EventHandle, Queue, (char *)TCFbuffer, &FileHandle);
  391.             if(NewOnly) {
  392.                 if((TCFbuffer->EventType == RECEIVE) || (TCFbuffer->EventType == POLLED_RECEIVE)) {
  393.                     Offset = TCFbuffer->FTROffset;
  394.                     for(Count = 1; Count <= TCFbuffer->FileCount; Count++) {
  395.                         /* Get information about the transferred files. */
  396.                         GetFileTransferBuffer((long)Offset, (char *)FTRbuffer, &FileHandle);
  397.                         Offset = Offset + 128;
  398.                         if(FTRbuffer->FileStatus != UNTOUCHED)
  399.                             ShowIt = FALSE;
  400.                     }
  401.                 }
  402.                 else
  403.                     /* Don't show sends or polled sends. */
  404.                     ShowIt = FALSE;
  405.             }
  406.             close(FileHandle);
  407.             if(ShowIt) {
  408.                 ++NewEvents;
  409.                 CorrectDate(TCFbuffer, Date);
  410.  
  411.                 switch(TCFbuffer->TransferType) {
  412.                     case FAX_200       : strcpy(TransType, "Fine"); break;
  413.                     case FAX_100       : strcpy(TransType, "Std "); break;
  414.                     case FILE_TRANSFER : strcpy(TransType, "CCP "); break;
  415.                     default            : strcpy(TransType, "    "); break;
  416.                     }
  417.  
  418.                 switch(TCFbuffer->EventStatus) {
  419.                     case COMPLETED     : strcpy(EventStatus, "Completed"); break;
  420.                     case WAITING       : strcpy(EventStatus, "Waiting  "); break;
  421.                     case DIALED        : strcpy(EventStatus, "Dialed   "); break;
  422.                     case SENDING       : strcpy(EventStatus, "Sending  "); break;
  423.                     case RECEIVING     : strcpy(EventStatus, "Receiving"); break;
  424.                     case ABORTED       : strcpy(EventStatus, "Aborted  "); break;
  425.                     default            : strcpy(EventStatus, "Error    "); break;
  426.                     }
  427.  
  428.                 switch(TCFbuffer->EventType) {
  429.                     case SEND            : strcpy(Action, "Send"); break;
  430.                     case RECEIVE         : strcpy(Action, "Recv"); break;
  431.                     case POLLED_SEND     : strcpy(Action, "Send(P)"); break;
  432.                     case POLLED_RECEIVE  : strcpy(Action, "Recv(P)"); break;
  433.                     default              : strcpy(Action, "Error"); break;
  434.                 }
  435.  
  436.                 fprintf(stdout, "\n%6d %14s %-8s %4s %9s %-6s%-24s",
  437.                 EventHandle,
  438.                 Date,
  439.                 Action,
  440.                 TransType,
  441.                 EventStatus,
  442.                 TCFbuffer->EventType ? "From:":"  To:",
  443.                 TCFbuffer->EventType ? TCFbuffer->SenderName : TCFbuffer->DestinationName);
  444.             }
  445.         }
  446.         if(NewEvents == 0)
  447.             fprintf(stdout, "None\n");
  448.         fprintf(stdout, "\n");
  449.     }
  450.     /* If a call to CASFindFirst returns an error 204h, the queue is empty. */
  451.     else if(-EventHandle == 0x204)
  452.         fprintf(stdout, "None\n");
  453.     else
  454.         if(EventHandle < 0)
  455.             CASError(CASHW, TRUE, -EventHandle);
  456. }
  457.  
  458. /*---------------------------------------------------------------------------*
  459.  *                                 FindEvent()                               *
  460.  *---------------------------------------------------------------------------*
  461.  * Finds whic queue the specified job resides in.  Searches the log queue    *
  462.  * first and then the task queue.  Returns the queue number.                 *
  463.  *---------------------------------------------------------------------------*
  464.  * Parameters:  int EventHandle - Event handle to find.                      *
  465.  * Return:      The queue in which the specified event is located in.        *
  466.  *---------------------------------------------------------------------------*/
  467. FindEvent(int EventHandle)
  468. {
  469.     int JobNo = 0;              /* Comparison job number.                    */
  470.  
  471.     /* Search the Log Queue. */
  472.     JobNo = CASFindFirst(ANY_STATUS,SEARCH_FORWARD,LOG_QUEUE);
  473.     if(JobNo == EventHandle)
  474.         return(LOG_QUEUE);
  475.     else {
  476.         while((JobNo = CASFindNext(LOG_QUEUE)) > 0) {
  477.             if(JobNo == EventHandle)
  478.             return(LOG_QUEUE);
  479.         }
  480.     }
  481.  
  482.     /* Search the Task Queue. */
  483.     JobNo = CASFindFirst(ANY_STATUS,SEARCH_FORWARD,TASK_QUEUE);
  484.     if(JobNo == EventHandle)
  485.         return(TASK_QUEUE);
  486.     else {
  487.         while((JobNo = CASFindNext(TASK_QUEUE)) > 0) {
  488.             if(JobNo == EventHandle)
  489.                 return(TASK_QUEUE);
  490.         }
  491.     }
  492.  
  493.     /* Event wasn't found - oops! */
  494.     return(-1);
  495. }
  496.  
  497. /*---------------------------------------------------------------------------*
  498.  *                               ShowJobStatus()                             *
  499.  *---------------------------------------------------------------------------*
  500.  * Shows the status of an individual job.  The information is retrieved      *
  501.  * from the file transfer records that are part of the control file.         *
  502.  *---------------------------------------------------------------------------*
  503.  * Parameters:  int EventHandle - Handle of event to show status for.        *
  504.  *              ECF *TCFbuffer - Uninitialized ECF structure, filled in with *
  505.  *                  Task Control info on return.                             *
  506.  *              FTR *FTRbuffer - Uninitialized FTR structure.                *
  507.  * Return:      none                                                         *
  508.  *---------------------------------------------------------------------------*/
  509. ShowJobStatus(int EventHandle, ECF *TCFbuffer, FTR *FTRbuffer, CECS *Current)
  510. {
  511.     char Date[20];              /* Date string.                              */
  512.     char msg[30];               /* Output message.                           */
  513.     long Offset;                /* FTR offset.                               */
  514.     int x;                      /* For loop variable.                        */
  515.     BYTE Queue;                 /* Queue to search.                          */
  516.     int len;                    /* String length.                            */
  517.     int CurrentEvent;           /* Current event handle.                     */
  518.  
  519.     /* If user is trying to get status on current event, call ShowCurrent-
  520.        EventStatus(). */
  521.     if((CurrentEvent = CASGetCurrentEventStatus(Current)) == EventHandle) {
  522.         ShowCurrentEvent(Current);
  523.         return;
  524.     }
  525.  
  526.     /* Have to find the correct queue first. */
  527.     Queue = FindEvent(EventHandle);
  528.  
  529.     /* Get information about the task. */
  530.     GetTaskBuffer(EventHandle, Queue, (char *)TCFbuffer, &FileHandle);
  531.     CorrectDate(TCFbuffer, Date);
  532.  
  533.     fprintf(stdout, "EVENT NUMBER    : %lu\n", EventNo);
  534.     fprintf(stdout, "FROM            : %s\n",  TCFbuffer->SenderName);
  535.     fprintf(stdout, "TO              : %s\n\n", TCFbuffer->DestinationName);
  536.     switch(TCFbuffer->EventStatus) {
  537.         case COMPLETED       : strcpy(msg, "Successfully completed"); break;
  538.         case WAITING         : strcpy(msg, "Waiting to be processed"); break;
  539.         case DIALED          : strcpy(msg, "Number has been dialed"); break;
  540.         case SENDING         : strcpy(msg, "Connection made -- sending"); break;
  541.         case RECEIVING       : strcpy(msg, "Connection made -- receiving"); break;
  542.         case ABORTED         : strcpy(msg, "Event was aborted"); break;
  543.         default              : {
  544.             strcpy(msg, "CCAM Error : ");
  545.             for(x = 1; x < UpperBound(CASEmsg); x++) {
  546.                 if(CASEmsg[x].ExitCode == -TCFbuffer->EventStatus) {
  547.                     strcat(msg, CASEmsg[x].Message);
  548.                     break;
  549.                 }
  550.             }
  551.         }
  552.     }
  553.     fprintf(stdout, "EVENT STATUS    : %s\n", msg);
  554.     fprintf(stdout, "ERRORS          : %d\n", TCFbuffer->ErrorCount);
  555.     switch(TCFbuffer->EventType) {
  556.         case SEND            : strcpy(msg, "Send"); break;
  557.         case RECEIVE         : strcpy(msg, "Receive"); break;
  558.         case POLLED_SEND     : strcpy(msg, "Polled Send"); break;
  559.         case POLLED_RECEIVE  : strcpy(msg, "Polled Receive"); break;
  560.         default              : strcpy(msg, "Error"); break;
  561.     }
  562.     fprintf(stdout, "EVENT TYPE      : %s\n", msg);
  563.     switch(TCFbuffer->TransferType) {
  564.         case FAX_200         : strcpy(msg, "200x200 Fax"); break;
  565.         case FAX_100         : strcpy(msg, "100x200 Fax"); break;
  566.         case FILE_TRANSFER   : strcpy(msg, "File Transfer"); break;
  567.         default              : strcpy(msg, "    "); break;
  568.     }
  569.     fprintf(stdout, "TRANSFER TYPE   : %s\n", msg);
  570.     fprintf(stdout, "DATE            : %s\n", Date);
  571.     fprintf(stdout, "CONNECT TIME    : %02d hr %02d min %02d sec\n",
  572.                                        (int)TCFbuffer->ConnectHours,
  573.                                        (int)TCFbuffer->ConnectMinutes,
  574.                                        (int)TCFbuffer->ConnectSeconds);
  575.  
  576.     fprintf(stdout, "NUMBER OF FILES : %d\n", TCFbuffer->FileCount);
  577.     fprintf(stdout, "COVER PAGE      : %s\n\n", TCFbuffer->SendCover ? "Yes":"No");
  578.  
  579.     if(TCFbuffer->FileCount > 0) {
  580.         fprintf(stdout, "FILE    FILE STATUS    SIZE/PAGES      NAME\n");
  581.         Offset = TCFbuffer->FTROffset;
  582.  
  583.         /* Get information about the transferred files. */
  584.         GetFileTransferBuffer(Offset, (char *)FTRbuffer, &FileHandle);
  585.         for(x = 1; x <= TCFbuffer->FileCount; x++) {
  586.             fprintf(stdout, "%3d", x);
  587.             switch(FTRbuffer->FileStatus) {
  588.                 case UNTOUCHED    : strcpy(msg, "Untouched"); break;
  589.                 case OPENED       : strcpy(msg, "Opened"); break;
  590.                 case MOVED        : strcpy(msg, "Saved"); break;
  591.                 case DELETED      : strcpy(msg, "Deleted"); break;
  592.                 case NOT_RECEIVED : strcpy(msg, "Not Received"); break;
  593.             }
  594.             fprintf(stdout, "     %-15s", msg);
  595.             switch(TCFbuffer->TransferType) {
  596.                 case FAX_200      :
  597.                 case FAX_100      : fprintf(stdout, "   %6d", FTRbuffer->PageCount);
  598.                                     break;
  599.                 case FILE_TRANSFER: fprintf(stdout, "%6ld   ", FTRbuffer->FileSize);
  600.                                     break;
  601.             }
  602.  
  603.             if((len = strlen(FTRbuffer->FileName)) > 40)
  604.                 fprintf(stdout, "    ...%-40s\n", FTRbuffer->FileName[80 - len]);
  605.             else
  606.                 fprintf(stdout, "       %-40s\n", FTRbuffer->FileName);
  607.  
  608.             /* Next FTR is always 128 bytes after the previous one. */
  609.             Offset = Offset + 128;
  610.             GetFileTransferBuffer(Offset, (char *)FTRbuffer, &FileHandle);
  611.         }
  612.         /* Close the Control File. */
  613.         close(FileHandle);
  614.     }
  615. }
  616.  
  617. /*---------------------------------------------------------------------------*
  618.  *                               ShowCurrentEvent()                          *
  619.  *---------------------------------------------------------------------------*
  620.  * Displays status information for the currently executing event.  The       *
  621.  * information is retrieved using the CASGetCurrentEventStatus call.         *
  622.  *---------------------------------------------------------------------------*
  623.  * Parameters:  CECS *Current - Uninitialized CECS structure, filled with    *
  624.  *                  current event info on return.                            *
  625.  * Return:      none                                                         *
  626.  *---------------------------------------------------------------------------*/
  627. ShowCurrentEvent(CECS *Current)
  628. {
  629.     char Date[20];              /* Date of current event.                    */
  630.     char msg[32];               /* Screen output buffer.                     */
  631.     int len;                    /* Used for string length.                   */
  632.     int x;                      /* Loop counter.                             */
  633.     int EventHandle;            /* Event handle.                             */
  634.  
  635.     if((EventHandle = CASGetCurrentEventStatus(Current)) == -NO_MORE_EVENTS)
  636.         fprintf (stdout,"No currently executing event.\n");
  637.     else {
  638.         CorrectDate((ECF *)Current, Date);
  639.  
  640.         fprintf(stdout, "EVENT NUMBER    : %d\n", EventHandle);
  641.         fprintf(stdout, "FROM            : %s\n",  Current->ControlFile.SenderName);
  642.         fprintf(stdout, "TO              : %s\n\n", Current->ControlFile.DestinationName);
  643.         switch(Current->ControlFile.EventStatus) {
  644.             case COMPLETED      : strcpy(msg, "Successfully completed"); break;
  645.             case WAITING        : strcpy(msg, "Waiting to be processed"); break;
  646.             case DIALED         : strcpy(msg, "Number has been dialed"); break;
  647.             case SENDING        : strcpy(msg, "Connection made -- sending"); break;
  648.             case RECEIVING      : strcpy(msg, "Connection made -- receiving"); break;
  649.             case ABORTED        : strcpy(msg, "Event was aborted"); break;
  650.             default              : {
  651.                 strcpy(msg, "CCAM Error : ");
  652.                 for(x = 1; x < UpperBound(CASEmsg); x++) {
  653.                     if(CASEmsg[x].ExitCode == -Current->ControlFile.EventStatus) {
  654.                         strcat(msg, CASEmsg[x].Message);
  655.                         break;
  656.                     }
  657.                 }
  658.             }
  659.         }
  660.         fprintf(stdout, "EVENT STATUS    : %s\n", msg);
  661.         fprintf(stdout, "ERRORS          : %d\n", Current->ControlFile.ErrorCount);
  662.         switch(Current->ControlFile.EventType) {
  663.             case SEND           : strcpy(msg, "Send"); break;
  664.             case RECEIVE        : strcpy(msg, "Receive"); break;
  665.             case POLLED_SEND    : strcpy(msg, "Polled Send"); break;
  666.             case POLLED_RECEIVE : strcpy(msg, "Polled Receive"); break;
  667.             default             : strcpy(msg, "Error"); break;
  668.             }
  669.         fprintf(stdout, "EVENT TYPE      : %s\n", msg);
  670.         switch(Current->ControlFile.TransferType) {
  671.             case FAX_200        : strcpy(msg, "200x200 Fax"); break;
  672.             case FAX_100        : strcpy(msg, "100x200 Fax"); break;
  673.             case FILE_TRANSFER  : strcpy(msg, "File Transfer"); break;
  674.             default             : strcpy(msg, "    "); break;
  675.             }
  676.         fprintf(stdout, "TRANSFER TYPE   : %s\n", msg);
  677.         switch(Current->ControlFile.EventStatus) {
  678.             case WAITING         : fprintf(stdout, "DATE            : Event in progress - board is waiting.\n"); break;
  679.             case DIALED          : fprintf(stdout, "DATE            : Event in progress - board is dialing.\n"); break;
  680.             case RECEIVING       : fprintf(stdout, "DATE            : Event in progress - board is receiving.\n"); break;
  681.             case ABORTED         :
  682.             case COMPLETED       :
  683.             case SENDING         : fprintf(stdout, "DATE            : %s\n", Date); break;
  684.         }
  685.         fprintf(stdout, "CONNECT TIME    : %02d hr %02d min %02d sec\n",
  686.                                            (int)Current->ControlFile.ConnectHours,
  687.                                            (int)Current->ControlFile.ConnectMinutes,
  688.                                            (int)Current->ControlFile.ConnectSeconds);
  689.  
  690.         fprintf(stdout, "NUMBER OF FILES : %d\n", Current->ControlFile.FileCount);
  691.         fprintf(stdout, "COVER PAGE      : %s\n\n", Current->ControlFile.SendCover ? "Yes":"No");
  692.  
  693.         fprintf(stdout, "     FILE STATUS      SIZE/PAGES    NAME\n");
  694.  
  695.         switch(Current->CurrentFileInTransit.FileStatus) {
  696.             case UNTOUCHED      : strcpy(msg, "Untouched"); break;
  697.             case OPENED         : strcpy(msg, "Opened"); break;
  698.             case MOVED          : strcpy(msg, "Moved"); break;
  699.             case DELETED        : strcpy(msg, "Deleted"); break;
  700.             case NOT_RECEIVED   : strcpy(msg, "Not Received"); break;
  701.             }
  702.             fprintf(stdout, "     %-15s", msg);
  703.             switch(Current->ControlFile.TransferType) {
  704.             case FAX_200        :
  705.             case FAX_100        : fprintf(stdout, "   %6d", Current->CurrentFileInTransit.PageCount);
  706.                                 break;
  707.             case FILE_TRANSFER  : fprintf(stdout, "%6ld   ", Current->CurrentFileInTransit.FileSize);
  708.                                 break;
  709.             }
  710.  
  711.             if((len = strlen(Current->CurrentFileInTransit.FileName)) > 40)
  712.             fprintf(stdout, "    ...%-40s\n", Current->CurrentFileInTransit.FileName[80 - len]);
  713.             else
  714.             fprintf(stdout, "       %-40s\n", Current->CurrentFileInTransit.FileName);
  715.         }
  716. }
  717.  
  718.  
  719. /*---------------------------------------------------------------------------*
  720.  *                             ShowState()                                   *
  721.  *---------------------------------------------------------------------------*
  722.  * Show the state of the autoanswer feature. A return of 0 rings indicates   *
  723.  * that the CCP hardware will not answer the phone line.                     *
  724.  *---------------------------------------------------------------------------*
  725.  * Parameters & Return: none                                                 *
  726.  *---------------------------------------------------------------------------*/
  727. void ShowState()
  728. {
  729.     int result;                 /* Function return value.                    */
  730.     int Rings;                  /* Number of rings before CCP answers phone. */
  731.  
  732.     ShowAll = FALSE;
  733.     if((result = CASAutoReceiveState(GET, &(char)Rings)) == AR_ON)
  734.         fprintf(stdout, "Auto answer set to %d rings.\n", Rings);
  735.     else if (result == AR_OFF)
  736.         fprintf (stdout, "Auto answer is off.\n");
  737.     else
  738.         CASError(CASBADARS, FALSE, -result);
  739. }
  740.  
  741. /*---------------------------------------------------------------------------*
  742.  *                             SetState()                                    *
  743.  *---------------------------------------------------------------------------*
  744.  * Set the state of the autoanswer feature. Valid values are 0 <= n <= 255.  *
  745.  * Trying to set the state to less than 0 results in setting the rings to 0. *
  746.  * Setting to greater than 255 results in setting to 255.                    *
  747.  *---------------------------------------------------------------------------*
  748.  * Parameters:  int Rings - The number of rings before the CCP answers the   *
  749.  *                  phone line.                                              *
  750.  * Return:      none                                                         *
  751.  *---------------------------------------------------------------------------*/
  752. void SetState(int Rings)
  753. {
  754.     int num;                    /* Number of rings to set autoanswer to.     */
  755.     int result;                 /* Function call return value.               */
  756.  
  757.     ShowAll = FALSE;
  758.  
  759.     /* Make sure that the number of rings is in acceptable range. */
  760.     if(Rings < 0)
  761.         num = 0;
  762.     else if(Rings > 255)
  763.         num = 255;
  764.     else
  765.         num = Rings;
  766.  
  767.     /* Set auto answer state - possibly off if rings = 0. */
  768.     if((result = CASAutoReceiveState(SET, &(char)num)) == AR_ON)
  769.         fprintf(stdout, "Auto answer set to %d rings.\n", num);
  770.     else if (result == AR_OFF)
  771.         fprintf(stdout, "Auto answer turned off.\n");
  772.     else
  773.         CASError(CASBADARS, FALSE, -result);
  774. }
  775.  
  776. /*---------------------------------------------------------------------------*
  777.  *                                Main                                       *
  778.  *---------------------------------------------------------------------------*
  779.  * Display information about tasks in the Receive, Task and Log queues. First*
  780.  * get the needed buffers. Then display information according to the command *
  781.  * line switches.                                                            *
  782.  *---------------------------------------------------------------------------*
  783.  *  Return: The DOS exit code is 0 if no errors are encountered, 1 for       *
  784.  *          commandline syntax errors, 2 for CCAM error, and 3 for DOS       *
  785.  *          errors.                                                          *
  786.  *---------------------------------------------------------------------------*/
  787. main(int argc, char **argv)
  788. {
  789.  
  790.     int result;                 /* DOS & CAS function return value.          */
  791.  
  792.     argc = ParseCommand(argc, argv, SwitchTable, TABLESIZE);
  793.  
  794.     /* Convert the event number to a long. */
  795.     EventNo = atol(JobNo);
  796.  
  797.     /* If help is wanted, print info and exit (with 0 exit code). */
  798.     if(Help)
  799.         CASHelp(DescTable, DESCSIZE, HelpTable, HELPSIZE);
  800.  
  801.     /* Insure that the Resident Scheduler is installed. */
  802.     if((result = CASGetInstalledState()) == INSTALLED) {
  803.         if(Diagnostics)
  804.             fprintf(stdout, " Resident scheduler installed.\n");
  805.     }
  806.     else {
  807.         if( result == NOTiOK )
  808.             CASError(CASNOHWO, TRUE, 0);
  809.         else
  810.             CASError(CASNOHWN, TRUE, 0);
  811.     }
  812.  
  813.     /* Redirect stdout to a file. */
  814.     if(RedirOut) {
  815.         if((ccout = fopen("OUTPUT.CC", "w")) == NULL)
  816.             CASError(CASOPENTEMP, TRUE, 0);
  817.         if(-1 == dup2(fileno(ccout), 1))
  818.             CASError(CASBADREDIR, TRUE, 0);
  819.     }
  820.  
  821.     /* Determine what information the user wants. */
  822.     if(!(TransmitOnly | LogOnly | NewOnly | CurrentEvent) && !(Diagnostics) && !(HardwareOnly) && (EventNo == 0))
  823.         ShowAll = TRUE;
  824.  
  825.     /* Display and/or set the autoreceive state if requested. */
  826.     if(ARState) ShowState();
  827.     if(AnswerOnRing != -1) SetState(AnswerOnRing);
  828.  
  829.     /* Get buffer for current event status information. */
  830.     TSTATbuffer = (CECS *)malloc(sizeof(CECS));
  831.     if(TSTATbuffer == NULL)
  832.         CASError(CASNOMEM, TRUE, 0);
  833.  
  834.     /* Get buffer for Task information. */
  835.     TCFbuffer = (ECF *)malloc(sizeof(ECF));
  836.     if(TCFbuffer == NULL)
  837.         CASError(CASNOMEM, TRUE, 0);
  838.  
  839.     /* Get buffer for File Transfer information. */
  840.     FTRbuffer = (FTR *)malloc(sizeof(FTR));
  841.     if(FTRbuffer == NULL)
  842.         CASError(CASNOMEM, TRUE, 0);
  843.  
  844.     /* Get buffer for Extended data. */
  845.     EDBbuffer = (EDB *)malloc(sizeof(EDB));
  846.     if(EDBbuffer == NULL)
  847.         CASError(CASNOMEM, TRUE, 0);
  848.  
  849.     /* If requested, run on-board diagnostics. Exit with error code if errors
  850.        are returned. */
  851.     if(Diagnostics)
  852.         RunDiagnostics();
  853.  
  854.     /* If /C option selected, show current event status */
  855.     if (CurrentEvent)
  856.         ShowCurrentEvent(TSTATbuffer);
  857.  
  858.     /* Show hardware status. */
  859.     if(HardwareOnly)
  860.         ShowHWStatus(TSTATbuffer, EDBbuffer);
  861.  
  862.     /* Show Task Queue status. */
  863.     if((!NewOnly) && (TransmitOnly | ShowAll)) {
  864.         fprintf(stdout, "PENDING EVENTS     : ");
  865.         ShowQueueStatus(ANY_STATUS, TASK_QUEUE, TCFbuffer, FTRbuffer);
  866.     }
  867.  
  868.     /* Show Log Queue status. */
  869.     if(NewOnly | LogOnly | ShowAll) {
  870.         if(NewOnly)
  871.             fprintf(stdout, "NEW RECEIVE EVENTS : ");
  872.         else
  873.             fprintf(stdout, "COMPLETED EVENTS   : ");
  874.         ShowQueueStatus(ANY_STATUS, LOG_QUEUE, TCFbuffer, FTRbuffer);
  875.     }
  876.  
  877.     /* Show Event status. */
  878.     if(EventNo != 0) {
  879.         ShowJobStatus(EventNo, TCFbuffer, FTRbuffer, TSTATbuffer);
  880.     }
  881.  
  882.     exit(0);
  883. }
  884.